package org.c41.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MockInvocationHandler implements InvocationHandler{

	private Object stub;
	
	public MockInvocationHandler(Object stub){
		this.stub=stub;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Method[] methods = stub.getClass().getDeclaredMethods();
		_findMethod:
		for(Method m : methods){
			m.setAccessible(true);
			Mock annotation = m.getAnnotation(Mock.class);
			if(annotation!=null 
					&& method.getName().equals(annotation.name())
					&& method.getReturnType().isAssignableFrom(annotation.returnType())){
				Class<?>[] paratype = annotation.paramType();
				Class<?>[] newtype = method.getParameterTypes();
				if(paratype.length==method.getParameterTypes().length){
					for(int i=0;i<paratype.length;i++){
						if(!paratype[i].isAssignableFrom(newtype[i])){
							continue _findMethod;
						}
					}
					return m.invoke(stub, args);
				}
			}
		}
		throw new NoSuchMethodException(method.toGenericString());
	}


}
